/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package systole.view.tabs.controllers;

import java.util.Observable;
import systole.domain.analysis.Analysis;
import systole.domain.analysis.results.AnalysisResult;
import systole.domain.analysis.results.ParameterAOD;
import systole.domain.analysis.results.ParameterAOS;
import systole.domain.analysis.results.ParameterCoord;
import systole.domain.analysis.results.ParameterIAR;
import systole.domain.analysis.results.ParameterT;
import systole.domain.signals.FinalSignal;
import systole.domain.signals.Segment;

/**
 *
 * @author jmj
 */
public class ResultsModel extends Observable {

    private boolean dirtyModel = false;
    private FinalSignal originalFinalSignal;
    private FinalSignal currentFinalSignal;
    private AnalysisResult originalResults;
    private AnalysisResult currentResults;

    /**
     *
     * @param analysis
     */
    public ResultsModel(Analysis analysis) {

        boolean newModel = (analysis.getAnalysisResult() == null);

        this.originalResults = analysis.getAnalysisResult();
        this.originalFinalSignal = analysis.getFinalSegment();

        this.currentFinalSignal = new FinalSignal();
        this.currentResults = new AnalysisResult();

        if (!newModel) {
            this.currentResults.setAod((ParameterAOD) this.originalResults.getAod().clone());
            this.currentResults.setAos((ParameterAOS) this.originalResults.getAos().clone());
            this.currentResults.setHeartRate(this.originalResults.getHeartRate());
            this.currentResults.setIar((ParameterIAR) this.originalResults.getIar().clone());
            this.currentResults.setT((ParameterT) this.originalResults.getT().clone());

            this.currentFinalSignal.setFinalSegment((Segment) this.originalFinalSignal.getFinalSegment().clone());
            this.currentFinalSignal.setFirstDerivatite((Segment) this.originalFinalSignal.getFirstDerivatite().clone());
            this.currentFinalSignal.setSecondDerivative((Segment) this.originalFinalSignal.getSecondDerivative().clone());
            this.currentFinalSignal.setThirdDerivative((Segment) this.originalFinalSignal.getThirdDerivative().clone());
            this.currentFinalSignal.setFourthDerivative((Segment) this.originalFinalSignal.getFourthDerivative().clone());
        }

    }

    /**
     * @return the dirtyModel
     */
    public boolean isDirtyModel() {
        return dirtyModel;
    }

    /**
     * @return the originalResults
     */
    public AnalysisResult getOriginalResults() {
        return originalResults;
    }

    /**
     * @return the currentResults
     */
    public AnalysisResult getCurrentResults() {
        return currentResults;
    }

    /**
     * @return the originalFinalSignal
     */
    public FinalSignal getOriginalFinalSignal() {
        return originalFinalSignal;
    }

    /**
     * @return the currentFinalSignal
     */
    public FinalSignal getCurrentFinalSignal() {
        return currentFinalSignal;
    }

    /**
     *
     * @param analysisResult
     * @param finalSignal
     */
    public void loadAnalysisResultCalculated(AnalysisResult analysisResult, FinalSignal finalSignal) {
        if ((analysisResult != null) && (finalSignal != null)) {

            if (this.originalResults != null) {
                this.originalResults.setAod(analysisResult.getAod());
                this.originalResults.setAos(analysisResult.getAos());
                this.originalResults.setHeartRate(analysisResult.getHeartRate());
                this.originalResults.setIar(analysisResult.getIar());
                this.originalResults.setT(analysisResult.getT());
            } else {
                this.originalResults = analysisResult;
            }

            this.currentResults.setAod((ParameterAOD) this.originalResults.getAod().clone());
            this.currentResults.setAos((ParameterAOS) this.originalResults.getAos().clone());
            this.currentResults.setHeartRate(this.originalResults.getHeartRate());
            this.currentResults.setIar((ParameterIAR) this.originalResults.getIar().clone());
            this.currentResults.setT((ParameterT) this.originalResults.getT().clone());

            if (this.originalFinalSignal != null) {
                this.originalFinalSignal.setFinalSegment(finalSignal.getFinalSegment());
                this.originalFinalSignal.setFirstDerivatite(finalSignal.getFirstDerivatite());
                this.originalFinalSignal.setSecondDerivative(finalSignal.getSecondDerivative());
                this.originalFinalSignal.setThirdDerivative(finalSignal.getThirdDerivative());
                this.originalFinalSignal.setFourthDerivative(finalSignal.getFourthDerivative());
            } else {
                this.originalFinalSignal = finalSignal;
            }

            this.currentFinalSignal.setFinalSegment((Segment) this.originalFinalSignal.getFinalSegment().clone());
            this.currentFinalSignal.setFirstDerivatite((Segment) this.originalFinalSignal.getFirstDerivatite().clone());
            this.currentFinalSignal.setSecondDerivative((Segment) this.originalFinalSignal.getSecondDerivative().clone());
            this.currentFinalSignal.setThirdDerivative((Segment) this.originalFinalSignal.getThirdDerivative().clone());
            this.currentFinalSignal.setFourthDerivative((Segment) this.originalFinalSignal.getFourthDerivative().clone());
        }
        this.dirtyModel = false;
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    public void restoreAOS() {
        this.currentResults.setAos((ParameterAOS) (((this.originalResults != null) && (this.originalResults.getAos() != null)) ? this.originalResults.getAos().clone() : null));
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    public void restoreAOD() {
        this.currentResults.setAod((ParameterAOD) (((this.originalResults != null) && (this.originalResults.getAod() != null)) ? this.originalResults.getAod().clone() : null));
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    public void restoreIAR() {
        this.currentResults.setIar((ParameterIAR) (((this.originalResults != null) && (this.originalResults.getIar() != null)) ? this.originalResults.getIar().clone() : null));
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    public void restoreT() {
        this.currentResults.setT((ParameterT) (((this.originalResults != null) && (this.originalResults.getT() != null)) ? this.originalResults.getT().clone() : null));
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    /**
     *
     * @param initPoint
     * @param endPoint
     */
    public void updateAOS(ParameterCoord initPoint, ParameterCoord endPoint) {
        if (this.currentResults.getAos() == null) {
            this.currentResults.setAos(new ParameterAOS());
        }
        this.markAsDirty();
        this.currentResults.getAos().setInitPos(initPoint);
        this.currentResults.getAos().setEndPos(endPoint);
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    /**
     *
     * @param initPoint
     * @param endPoint
     */
    public void updateAOD(ParameterCoord initPoint, ParameterCoord endPoint) {
        if (this.currentResults.getAod() == null) {
            this.currentResults.setAod(new ParameterAOD());
        }
        this.markAsDirty();
        this.currentResults.getAod().setInitPos(initPoint);
        this.currentResults.getAod().setEndPos(endPoint);
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    /**
     *
     * @param initPoint
     * @param endPoint
     */
    public void updateT(ParameterCoord initPoint, ParameterCoord endPoint) {
        if (this.currentResults.getT() == null) {
            this.currentResults.setT(new ParameterT());
        }
        this.markAsDirty();
        this.currentResults.getT().setInitPos(initPoint);
        this.currentResults.getT().setEndPos(endPoint);
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    /**
     *
     * @param initPoint
     * @param endPoint
     */
    public void updateIAR(ParameterCoord initPoint, ParameterCoord endPoint) {
        if (this.currentResults.getIar() == null) {
            this.currentResults.setIar(new ParameterIAR());
        }
        this.markAsDirty();
        this.currentResults.getIar().setInitPos(initPoint);
        this.currentResults.getIar().setEndPos(endPoint);
        this.setChanged();
        this.notifyObservers(this.currentResults);
    }

    public void save() {
        if (this.isDirtyModel()) {
            // no clono porque si ya existía pierdo el ID y sería otro objeto (registro en la bd)
            if (this.originalResults == null) {
                this.originalResults = new AnalysisResult();
            }
            this.originalResults.setAod(this.currentResults.getAod());
            this.originalResults.setAos(this.currentResults.getAos());
            this.originalResults.setHeartRate(this.currentResults.getHeartRate());
            this.originalResults.setIar(this.currentResults.getIar());
            this.originalResults.setT(this.currentResults.getT());

            // no clono porque si ya existía pierdo el ID y sería otro objeto (registro en la bd)
            if (this.originalFinalSignal == null) {
                this.originalFinalSignal = new FinalSignal();
            }
            this.originalFinalSignal.setFinalSegment(this.currentFinalSignal.getFinalSegment());
            this.originalFinalSignal.setFirstDerivatite(this.currentFinalSignal.getFirstDerivatite());
            this.originalFinalSignal.setSecondDerivative(this.currentFinalSignal.getSecondDerivative());
            this.originalFinalSignal.setThirdDerivative(this.currentFinalSignal.getThirdDerivative());
            this.originalFinalSignal.setFourthDerivative(this.currentFinalSignal.getFourthDerivative());
            this.dirtyModel = false;
        }
    }

    private void markAsDirty() {
        this.dirtyModel = true;
    }
}
